<!-- src/views/admin/UserRoles.vue -->
<template>
  <div class="user-roles-container">
    <el-card class="user-roles-card" :body-style="{ padding: '20px' }">
    <div class="page-header">
      <h2>用户角色管理</h2>
      <p class="subtitle">管理系统用户的角色分配</p>
    </div>

    
      <div class="controls">
        <el-input
          v-model="filterUsername"
          placeholder="输入用户名搜索..."
          clearable
          @clear="fetchUserList"
          @keyup.enter="fetchUserList"
          class="search-input"
        >
          <template #prefix>
            <el-icon><Search /></el-icon>
          </template>
        </el-input>
        <el-button type="primary" @click="fetchUserList" class="search-btn">
          <el-icon><Search /></el-icon>
          搜索
        </el-button>
      </div>

      <el-table
        v-loading="loadingUsers"
        :data="users"
        stripe
        class="user-table"
        @current-change="onCurrentUserChange"
        highlight-current-row
      >
        <el-table-column type="index" width="60" label="#" />
        <el-table-column prop="username" label="用户名">
          <template #default="{ row }">
            <div class="user-info">
              <el-avatar :size="32" class="user-avatar">
                {{ row.username.charAt(0).toUpperCase() }}
              </el-avatar>
              <span>{{ row.username }}</span>
            </div>
          </template>
        </el-table-column>
        <el-table-column prop="nickname" label="昵称" />
        <el-table-column label="操作" width="120">
          <template #default="{ row }">
            <el-button 
              type="primary" 
              link
              class="assign-btn"
              @click="selectUser(row)"
            >
              <el-icon><UserFilled /></el-icon>
              分配角色
            </el-button>
          </template>
        </el-table-column>
      </el-table>

      <div class="pagination">
        <el-pagination
          background
          layout="prev, pager, next, jumper, sizes, total"
          :current-page="pageNum"
          :page-size="pageSize"
          :page-sizes="[10, 20, 50]"
          :total="totalUsers"
          @current-change="onUserPageChange"
          @size-change="onUserSizeChange"
        />
      </div>
    </el-card>

    <!-- 分配角色对话框 -->
    <el-dialog 
      title="分配角色" 
      v-model="dialogVisible" 
      width="480px"
      class="role-dialog"
      destroy-on-close
    >
      <div v-if="selectedUser" class="selected-user-info">
        <el-avatar :size="48" class="user-avatar">
          {{ selectedUser.username.charAt(0).toUpperCase() }}
        </el-avatar>
        <div class="user-details">
          <h3>{{ selectedUser.username }}</h3>
          <p>{{ selectedUser.nickname }}</p>
        </div>
      </div>

      <div class="role-selection">
        <h4>选择角色</h4>
        <el-checkbox-group
          v-model="checkedRoleIds"
          class="role-checkbox-group"
        >
          <el-checkbox 
            v-for="role in allRoles" 
            :key="role.id" 
            :label="role.id"
            class="role-checkbox"
          >
            {{ role.name }}
          </el-checkbox>
        </el-checkbox-group>
      </div>

      <template #footer>
        <div class="dialog-footer">
          <el-button @click="dialogVisible = false">取消</el-button>
          <el-button 
            type="primary" 
            :loading="saving" 
            @click="onSaveRoles"
            class="save-btn"
          >
            保存更改
          </el-button>
        </div>
      </template>
    </el-dialog>
  </div>
</template>
  
<script setup>
import { ref, onMounted } from "vue";
import { ElMessage } from "element-plus";
import { pageUsers } from "@/api/users";
import { listAllRoles, getUserRoles, assignUserRoles } from "@/api/userRoles";

// 用户列表分页状态
const loadingUsers = ref(false);
const users = ref([]);
const totalUsers = ref(0);
const pageNum = ref(1);
const pageSize = ref(10);
const filterUsername = ref("");

// 分配角色对话框状态
const dialogVisible = ref(false);
const selectedUser = ref(null);
const allRoles = ref([]);
const checkedRoleIds = ref([]);
const saving = ref(false);

// 分页 & 列表
function fetchUserList() {
  loadingUsers.value = true;
  pageUsers({
    pageNum: pageNum.value,
    pageSize: pageSize.value,
    username: filterUsername.value,
  })
    .then((res) => {
      users.value = res.data.items;
      totalUsers.value = res.data.total;
    })
    .finally(() => (loadingUsers.value = false));
}

// 分页回调
function onUserPageChange(p) {
  pageNum.value = p;
  fetchUserList();
}
function onUserSizeChange(sz) {
  pageSize.value = sz;
  pageNum.value = 1;
  fetchUserList();
}

// 打开「选择用户」操作，也可以直接在表格行点击
function selectUser(user) {
  selectedUser.value = user;
  dialogVisible.value = true;
  loadUserRoles(user.id);
}

// 加载所有角色 & 当前用户已分配角色
function loadAllRoles() {
  listAllRoles().then((res) => {
    allRoles.value = res.data.items; // [{id,name,…},…]
  });
}
function loadUserRoles(userId) {
  getUserRoles(userId).then((res) => {
    const roleNames = res.data.roleNames || [];
    checkedRoleIds.value = allRoles.value
      .filter((role) => roleNames.includes(role.name))
      .map((role) => role.id);
  });
}

// 保存分配
function onSaveRoles() {
  if (!selectedUser.value) return;
  saving.value = true;
  assignUserRoles({
    userId: selectedUser.value.id,
    roleIds: checkedRoleIds.value,
  })
    .then(() => {
      ElMessage.success("分配成功");
      dialogVisible.value = false;
    })
    .finally(() => (saving.value = false));
}

// 初始加载
onMounted(() => {
  fetchUserList();
  loadAllRoles();
});
</script>
  
<style scoped>
.user-roles-container {
  padding: 24px;
  background-color: #f6f8fa;
  min-height: 100vh;
}

.page-header {
  margin-bottom: 24px;
}

.page-header h2 {
  font-size: 24px;
  color: #1f2937;
  margin: 0;
}

.subtitle {
  color: #6b7280;
  margin: 8px 0 0;
}

.user-roles-card {
  background: #fff;
  border-radius: 12px;
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
  transition: all 0.3s ease;
}

.user-roles-card:hover {
  box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
}

.controls {
  display: flex;
  gap: 12px;
  margin-bottom: 20px;
}

.search-input {
  width: 300px;
}

.search-input :deep(.el-input__wrapper) {
  border-radius: 8px;
  transition: all 0.3s ease;
}

.search-input :deep(.el-input__wrapper:hover) {
  box-shadow: 0 0 0 1px #6366f1;
}

.search-input :deep(.el-input__wrapper.is-focus) {
  box-shadow: 0 0 0 1px #6366f1;
}

.search-btn {
  padding: 8px 20px;
  border-radius: 8px;
  transition: all 0.3s ease;
}

.search-btn:hover {
  transform: translateY(-1px);
  box-shadow: 0 4px 6px rgba(99, 102, 241, 0.2);
}

.user-table {
  margin-top: 16px;
  border-radius: 8px;
  overflow: hidden;
}

.user-table :deep(.el-table__row) {
  transition: all 0.3s ease;
}

.user-table :deep(.el-table__row:hover) {
  background-color: #f9fafb !important;
}

.user-info {
  display: flex;
  align-items: center;
  gap: 12px;
}

.user-avatar {
  background: linear-gradient(135deg, #6366f1, #8b5cf6);
  color: white;
  font-weight: 500;
  transition: transform 0.3s ease;
}

.user-avatar:hover {
  transform: scale(1.1);
}

.assign-btn {
  display: flex;
  align-items: center;
  gap: 4px;
  font-weight: 500;
  transition: all 0.3s ease;
}

.assign-btn:hover {
  color: #6366f1;
  transform: translateX(2px);
}

.pagination {
  margin-top: 20px;
  display: flex;
  justify-content: flex-end;
}

.role-dialog :deep(.el-dialog__header) {
  margin: 0;
  padding: 20px 24px;
  border-bottom: 1px solid #e5e7eb;
}

.role-dialog :deep(.el-dialog__body) {
  padding: 24px;
}

.role-dialog :deep(.el-dialog__footer) {
  padding: 16px 24px;
  border-top: 1px solid #e5e7eb;
}

.selected-user-info {
  display: flex;
  align-items: center;
  gap: 16px;
  padding: 16px;
  background: #f9fafb;
  border-radius: 8px;
  margin-bottom: 24px;
  transition: all 0.3s ease;
}

.selected-user-info:hover {
  background: #f3f4f6;
}

.user-details h3 {
  margin: 0;
  font-size: 18px;
  color: #1f2937;
}

.user-details p {
  margin: 4px 0 0;
  color: #6b7280;
}

.role-selection h4 {
  margin: 0 0 16px;
  color: #374151;
}

.role-checkbox-group {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
  gap: 12px;
}

.role-checkbox {
  margin-right: 0;
  padding: 12px;
  border: 1px solid #e5e7eb;
  border-radius: 8px;
  transition: all 0.2s ease;
}

.role-checkbox:hover {
  background: #f9fafb;
  border-color: #d1d5db;
  transform: translateY(-1px);
}

.dialog-footer {
  display: flex;
  justify-content: flex-end;
  gap: 12px;
}

.save-btn {
  min-width: 100px;
  transition: all 0.3s ease;
}

.save-btn:hover {
  transform: translateY(-1px);
  box-shadow: 0 4px 6px rgba(99, 102, 241, 0.2);
}

@media (max-width: 768px) {
  .user-roles-container {
    padding: 16px;
  }

  .controls {
    flex-direction: column;
  }

  .search-input {
    width: 100%;
  }

  .role-checkbox-group {
    grid-template-columns: 1fr;
  }
}
</style>
  